<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        .one,
        .two,
        .three,
        .four {
            border: 1px solid #333;
            padding: 5px;
            margin: 5px;
        }
    </style>
</head>

<body>
    <div id="app">
        <p>{{a}}---{{b}}</p>
        <p>
            <button @click="a++">a++</button>
            <button @click="b++">b++</button>
        </p>
        <com-a></com-a>
    </div>
</body>
<script>

   
    var comC = {
        // 接收四个函数 => 箭头函数
        inject: ["getA", "getB", "setA", "setB"],
        data() {
            return {

            }
        },
        template: `<div class="one">
            <p>这是组件C---{{getA()}}---{{getB()}}</p>
            <p>
                <button @click="setA(getA()+1)">a++</button>
                <button @click="setB(getB()+1)">b++</button>
            </p>
        </div>`,
        mounted() {
            console.log("组件C", this.getA);
            console.log("组件C", this.setA);
        }
    }

    var comB = {
        inject: ["getA", "getB"],  // 接收定死的两个值
        data() {
            return {

            }
        },
        template: `<div class="one">
            <p>这是组件B---{{getA()}}---{{getB()}}</p>
            <com-c></com-c>
        </div>`,
        components: {
            comC: comC,
        },

    }

    var comA = {
        data() {
            return {

            }
        },
        template: `<div class="one">
                <p>这是组件A</p>
                <com-b></com-b>
        </div>`,
        components: {
            comB: comB,
        }
    }


    // provide / inject   => 一般情况下,需要一起使用
    // 允许一个祖先组件(父代组件)向其所有子孙后代(子代组件)注入一个依赖，不论组件层次有多深  => 子代组件可以使用父代组件的数据(前提:需要inject)

    // provide: 父组件向所有子孙后代(子代组件)注入一个依赖(对象)
    // provide 选项应该是一个对象或返回一个对象的函数。对象中的数据就是注入子代组件的数据

    // inject:  对应属性名,引入父组件注入的数据
    // inject 选项应该是一个字符串数组(),或者一个对象
    // 


    // 根实例/组件/应用
    var vm = new Vue({
        el: "#app",
        data: {
            a: 1,
            b: 2,
        },
        components: { // 在当前组件(根组件) 注册了两个子组件 (comA comB)
            // 键名 => 组件名
            // 键值 => 组件的配置对象 
            comA: comA,
        },
        // provide的配置是一个返回对象的函数 (此时函数的this指向 => 当前实例, 可以使用实例中的数据)
        provide: function () {
            console.log("provide", this);
            return {
                // 传值  => 死数据  
                // a: this.a,  // a = 1
                // b: this.b,  // b = 2;

                // 传箭头函数(箭头函数this -> 指向当前实例(根实例))  => 提供了即时获取和改变数据的方法(响应式)
                getA: () => {
                    console.log("getA被调用");
                    return this.a;
                },
                setA: (v) => this.a = v,
                getB: () => {
                    console.log("getB被调用");
                    return this.b;
                },
                setB: (v) => this.b = v,
            }
        }
    })



</script>

</html>